/**
 1 * 安卓白金英雄坛制作组 <br>
 *0 文件名：Item.java <br>
 * 创建时间：2013-7-27 下午10:38:20 <br>
 * 所属项目：GmudEX <br>
 * @author 12548 <br>
 */
package lostland.gmud.exv2.data;

import com.orhanobut.logger.Logger;

import java.util.ArrayList;
import java.util.Collection;

import lostland.gmud.exv2.Gmud;

/**
 * 类名：Item <br>
 * 说明：物品
 *
 * @author 12548
 */
public class Item {

	public static Item getNullItem() {
		if(nullItem == null)
			nullItem = Item.generateItem(0, -1);
		return nullItem;
	}

	public static final class ItemQuality {

		private static final String QUALITY_PREFIX[] = new String[]{
				"普通", // 0
				"美味的", "变质的", // 2
				"优质的", "劣质的", // 4
				"锋利的", "有缺口的", "弯曲的", "生锈的", "精炼的", "沉重的", "轻盈的", "坚韧的", "破败的", //13
				"加厚的", "轻薄的", "美丽的", "枯萎的" // 17
		};

		private static final int QUALITY_ISGOOD[] = new int[]{
				0,
				1, -1,
				1, -1,
				1, -1, -1, -1, 1, 0, 0, 1, -1,
				1, -1, 1, -1
		};


		public static final int QUALITY_FOOD[] = new int[]{1, 2};
		public static final int QUALITY_MEDIC[] = new int[]{3, 4};
		public static final int QUALITY_EDGE[] = new int[]{5, 7};
		public static final int QUALITY_HEAVY[] = new int[]{10, 10};
		public static final int QUALITY_METAL[] = new int[]{8, 9};
		public static final int QUALITY_LEATHER[] = new int[]{12, 13};
		public static final int QUALITY_ARMOR[] = new int[]{14, 15};
		public static final int QUALITY_FLOWER[] = new int[]{16, 17};


		public boolean isGood() {
			return QUALITY_ISGOOD[id] > 0;
		}

		public boolean isBad() {
			return QUALITY_ISGOOD[id] < 0;
		}


		public static ItemQuality getAGoodQuality(Collection<Integer> texture) {
			int t = 0;
			int s = 0;
			for (int i : texture) {
				if (QUALITY_ISGOOD[i] > 0) {
					s++;
				}
			}

			for (int i : texture) {
				if (QUALITY_ISGOOD[i] > 0) {
					t = i;
					if (Math.random() < (1.0 / s)) {
						break;
					}
				}
			}

			return new ItemQuality(t);
		}

		public static ItemQuality getANormalQuality(Collection<Integer> texture) {
			int t = 0;
			int s = 0;
			for (int i : texture) {
				if (QUALITY_ISGOOD[i] == 0) {
					s++;
				}
			}

			for (int i : texture) {
				if (QUALITY_ISGOOD[i] == 0) {
					t = i;
					if (Math.random() < (1.0 / s)) {
						break;
					}
				}
			}

			return new ItemQuality(t);
		}

		public static ItemQuality getABadQuality(Collection<Integer> texture) {
			int t = 0;
			int s = 0;
			for (int i : texture) {
				if (QUALITY_ISGOOD[i] < 0) {
					s++;
				}
			}

			for (int i : texture) {
				if (QUALITY_ISGOOD[i] < 0) {
					t = i;
					if (Math.random() < (1.0 / s)) {
						break;
					}
				}
			}

			return new ItemQuality(t);
		}

		private int id;

		/**
		 * @param id
		 */
		public ItemQuality(int id) {
			setId(id);
		}

		/**
		 * @return id
		 */
		public int getId() {
			return id;
		}

		/**
		 * @param id 要设置的 id
		 */
		public void setId(int id) {
			this.id = id;
		}

		public String getPrefix() {
			if (id > 0 && id < QUALITY_PREFIX.length)
				return QUALITY_PREFIX[id];
			else
				return "";
		}

		/* （非 Javadoc）
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + id;
			return result;
		}

		/* （非 Javadoc）
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ItemQuality other = (ItemQuality) obj;
			return id == other.id;
		}
	}

	private ItemQuality quality = new ItemQuality(0);

	public int x_quality = 0; // FIXME

	public static final int ROPE_INDEX = 19;
	public static final int TRIANGLE_INDEX = 99;

	private int template_id = 0;

	public int ex_level = 0;

	public int enhanceable = 0;

	public int drop_rate = 100;

	/**
	 * 物品强化加值
	 */
	public static final String ex_prefix[] = new String[]{
			"    ", "红羽", "紫霞", "碧水", "观日", "凌虚", "秋骊", "松鹤", "水寒", "雪霁",
			"凤翎", "龙翔", "七杀", "破军", "贪狼", "天问", "罗刹", "修罗", "菩提", "青冥",
			"霸王", "天龙", "炼狱", "浩然", "天微", "勾陈", "紫薇", "昊天", "无极"
	};

	public ArrayList<Rune> runes = new ArrayList<>();

	public int getRuneValue(int a0, int a1) {
		int t = 0;
		for (Rune i : runes) {
			if (i.a0 == a0 && i.a1 == a1) {
				t += i.getValue();
			}
		}
		return t;
	}

	public String getRuneName(int a0, int a1) {
		String t = "";
		for (Rune i : runes)
			if (i.a0 == a0 && i.a1 == a1) {
				t += "【" + i.getStr() + "】";
			}
		return t;
	}

	public boolean haveRune(Rune rune) {
		return runes.contains(rune);
	}

	public boolean haveRune(int a0, int a1, int a2) {
		return haveRune(new Rune(a0, a1, a2));
	}

	public void addRune(Rune rune) {
		runes.add(rune);
	}


	public void randomUpdate(int lvl) {
		if (equals(getNullItem())) return;

		ex_level = 0;
		runes.clear();

		for (int i = 0; i < lvl; i++) {
			randomUpdate();
		}
	}


	private void randomUpdate() {
		if (ex_level >= ex_prefix.length - 1) return;
		ex_level++;
		if (ex_level > 3 && (ex_level - 1) % 3 == 0) {
			runes.add(getARandomAvaliableRune());
		}
	}

	public Rune getARandomAvaliableRune() {
		ArrayList<Rune> all = getAvaliableRunes();

		return all.get((int) (Math.random() * all.size()));
	}

	/**
	 * @return
	 */
	public ArrayList<Rune> getAvaliableRunes() {
		int ladder = (ex_level - 1) / 3;
		int a0 = ladder % 2;
		if (getKind() != 2 && a0 == 1) {
			a0 = 2;
		}

		int a2min = (ladder + 2) / 3 - 1;
		int a2max = Math.min(ladder - 1, 4);

		ArrayList<Rune> all = new ArrayList<>();
		for (int i = 0; i < Rune.runes[a0].length; i++) {
			for (int j = a2min; j <= a2max; j++) {
				all.add(new Rune(a0, i, j));
			}
		}
		return all;
	}

	private static Item nullItem;

	public static Item generateItem(int template_id, int luckness) {
		return generateItem(Gmud.getWp().get(template_id), luckness);
	}


	public static Item generateItem(ItemTemplate template, int luckness) {
		Item itm = new Item();
		itm.template_id = template.id;
		itm.enhanceable = 3;

		if (luckness > -1) {
			int bad = (100 - luckness) / 2;
			int normal = bad + luckness / 3;

			int rnd = Gmud.rand.nextInt(100);

			itm.enhanceable += (rnd + luckness - 100) / 50;

			if (rnd <= bad) {
				itm.setQuality(ItemQuality.getABadQuality(template.texture));
			} else if (rnd <= normal) {
				itm.setQuality(ItemQuality.getANormalQuality(template.texture));
			} else {
				itm.setQuality(ItemQuality.getAGoodQuality(template.texture));
			}
		}

		return itm;
	}


	/**
	 *
	 */
	public Item() {
	}

	/**
	 * 该物品是否可以丢弃，一般都是可以的<br>
	 * a6>0为物品重量等级
	 *
	 * @return true
	 */
	public boolean canDrop() {
		return getA6() > -1;
	}

	/**
	 * 获取物品的主属性。
	 * <pre>
	 * 如果物品为食物，主属性为服用增加的食物值；
	 * 如果物品为药物，主属性决定药物效果；
	 * 如果物品为武器，主属性为装备增加的攻击力；
	 * 如果物品为装备，主属性为装备增加的防御力。
	 * </pre>
	 *
	 * @return 要获取的主属性
	 */
	public int getA3() {
		int value = getTemplate().getA3();
		value *= 1 + ex_level * 0.1;
		value += ex_level;
		switch (quality.id) {
			case 1: //美味的
				value *= 1.6;
				break;
			case 2: //变质的
				value *= 0.2;
				break;
			case 3: //优质的
				value *= 1.25;
				break;
			case 4: //劣质的
				value *= 0.75;
				break;
			case 5: //锋利的
				value *= 1.3;
				break;
			case 6: //有缺口的
				value *= 0.75;
				break;
			case 7: //弯曲的
				value *= 0.8;
				break;
			case 8: //生锈的
				value *= 0.7;
				break;
			case 9: //精炼的
				value *= 1.25;
				break;
			case 10: //沉重的
				value *= 1.4;
				break;
			case 11: //轻盈的
				break;
			case 12: //坚韧的
				value *= 1.25;
				break;
			case 13: //破败的
				value *= 0.5;
				break;
			case 14: //加厚的
				value *= 1.3;
				break;
			case 15: //轻薄的
				value *= 0.75;
				break;
			case 16: //美丽的
				break;
			case 17: //枯萎的
				break;
		}
		return value;
	}

	/**
	 * 获取物品的副属性。<br>
	 * <pre>
	 * 如果物品为食物，副属性为服用增加的饮水值；
	 * 如果物品为武器或装备，副属性为装备增加的命中值；
	 * </pre>
	 *
	 * @return 副属性
	 */
	public int getA4() {
		int value = getTemplate().a4;

		switch (quality.id) {
			case 1: //美味的
				value *= 1.3;
				break;
			case 2: //变质的
				value *= 0.2;
				break;
			case 3: //优质的
				break;
			case 4: //劣质的
				break;
			case 5: //锋利的
				break;
			case 6: //有缺口的
				break;
			case 7: //弯曲的
				value -= 2;
				break;
			case 8: //生锈的
				break;
			case 9: //精炼的
				break;
			case 10: //沉重的
				value -= 5;
				break;
			case 11: //轻盈的
				break;
			case 12: //坚韧的
				break;
			case 13: //破败的
				break;
			case 14: //加厚的
				break;
			case 15: //轻薄的
				break;
			case 16: //美丽的
				break;
			case 17: //枯萎的
				break;
		}
		return value;
	}


	/**
	 * 获取物品的第三属性。<br>
	 * 武器或装备的装备增加的回避值。
	 *
	 * @return a5
	 */
	public int getA5() {
		int value = getTemplate().a5;

		switch (quality.id) {
			case 1: //美味的
				break;
			case 2: //变质的
				break;
			case 3: //优质的
				break;
			case 4: //劣质的
				break;
			case 5: //锋利的
				break;
			case 6: //有缺口的
				break;
			case 7: //弯曲的
				break;
			case 8: //生锈的
				break;
			case 9: //精炼的
				break;
			case 10: //沉重的
				value -= 5;
				break;
			case 11: //轻盈的
				value += 5;
				break;
			case 12: //坚韧的
				break;
			case 13: //破败的
				break;
			case 14: //加厚的
				break;
			case 15: //轻薄的
				break;
			case 16: //美丽的
				break;
			case 17: //枯萎的
				break;
		}
		return value;
	}

	/**
	 * 获取物品售价。
	 *
	 * @return cost
	 */
	public int getCost() {
		int value = getTemplate().cost;
		value *= (1 + ex_level);
		switch (quality.id) {
			case 1: //美味的
				value *= 1.6;
				break;
			case 2: //变质的
				value *= 0.2;
				break;
			case 3: //优质的
				value *= 1.25;
				break;
			case 4: //劣质的
				value *= 0.75;
				break;
			case 5: //锋利的
				value *= 1.3;
				break;
			case 6: //有缺口的
				value *= 0.75;
				break;
			case 7: //弯曲的
				value *= 0.8;
				break;
			case 8: //生锈的
				value *= 0.7;
				break;
			case 9: //精炼的
				value *= 1.25;
				break;
			case 10: //沉重的
				value *= 1.1;
				break;
			case 11: //轻盈的
				value *= 0.9;
				break;
			case 12: //坚韧的
				value *= 1.25;
				break;
			case 13: //破败的
				value *= 0.5;
				break;
			case 14: //加厚的
				value *= 1.3;
				break;
			case 15: //轻薄的
				value *= 0.75;
				break;
			case 16: //美丽的
				value *= 100;
				break;
			case 17: //枯萎的
				value *= 0.1;
				break;
		}
		return value;
	}


	/**
	 * 获取物品名称。
	 * <pre>
	 * 不再显示等级前缀，改为后缀。
	 * </pre>
	 *
	 * @return 在物品栏中显示的名称
	 */
	public String getName() {
		if (ex_level == 0)
			return quality.getPrefix() + getTemplate().name;
		else
			return quality.getPrefix() + getTemplate().name + "+" + ex_level;
	}

	/**
	 * @param name 要设置的 name
	 */
	public void setName(String name) {
		getTemplate().name = name;
	}

	/**
	 * @return id
	 */
	public int getId() {
		return getTemplate().id;
	}

	/**
	 * @return kind
	 */
	public int getKind() {
		return getTemplate().kind;
	}

	/**
	 * @return subkind
	 */
	public int getSubkind() {
		return getTemplate().subkind;
	}


	/**
	 * a6记录是否可以丢弃和物品的重量等级<br>
	 * -1:不可丢弃；<br>
	 * 1:极轻 2:很轻 3:不轻 4:正常 5:不重 6:很重 7:极重
	 *
	 * @return a6
	 */
	public int getA6() {
		return getTemplate().a6;
	}

	/**
	 * @return des
	 */
	public String getDes() {
		String des = getTemplate().des;
		if (!runes.isEmpty()) {
			des += "上面有一行小字：";
			for (Rune i : runes) {
				des += i.getStr();
			}
		}
		return des;
	}

	public ItemQuality getQuality() {
		return quality;
	}


	public void setQuality(ItemQuality quality) {
		this.quality = quality;
	}

	/* （非 Javadoc）
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ex_level;
		result = prime * result + ((quality == null) ? 0 : quality.hashCode());
		result = prime * result + ((runes == null) ? 0 : runes.hashCode());
		result = prime * result
				+ ((getTemplate() == null) ? 0 : getTemplate().hashCode());
		return result;
	}

	/* （非 Javadoc）
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Item other = (Item) obj;
		if (ex_level != other.ex_level)
			return false;
		if (ex_level != other.ex_level)
			return false;
		if (quality == null) {
			if (other.quality != null)
				return false;
		} else if (!quality.equals(other.quality))
			return false;
		if (runes == null) {
			if (other.runes != null)
				return false;
		} else if (!runes.equals(other.runes))
			return false;
		else if (!getTemplate().equals(other.getTemplate()))
			return false;
		return true;
	}

	public int getTriggerOnUse() {
		return getTemplate().triggerOnUse;
	}

	/**
	 * 判断物品是否存在
	 *
	 * @param item 要检查的物品
	 * @return 如果物品不为null或ID>0则返回true。
	 */
	public static boolean notNull(Item item) {
		if (item == null)
			return false;
		return item.template_id > 0;
	}

	/**
	 * 获取物品模板。
	 *
	 * @return 物品模板
	 */
	public ItemTemplate getTemplate() {
		if(template_id >= Gmud.getWp().size()){
			Logger.e("Fetal Error : template id %d is out of %d", template_id, Gmud.getWp().size());
			template_id = 0;
		}
		return Gmud.getWp().get(template_id);
	}

}
